/***********************************************************************************************************************
 * Copyright (c) 2010 Ronald D. Kurr. Licensed under the Apache License, Version 2.0 (the "License"); you may not use
 * this file except in compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software
 * distributed under th License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 **********************************************************************************************************************/

package org.kurron.web.service;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * This object will hold the mappings between long and shortened URLs.  It uses in-memory maps
 * which means the mappings won't survive a system restart.
 */
@Service
public class DefaultUrlMapper implements UrlMapper
{
    /**
     * This contains the mapping from shortened URLs to the original URLs.
     */
    private final Map<String, URL> theShortToLongMap = new HashMap<String, URL>( 32 );

    /**
     * This contains the mapping from the original URLs to the shortened URLs.
     */
    private final Map<URL, String> theLongToShortMap = new HashMap<URL, String>( 32 );

    /**
     * Utility class that knows how to properly build URLs.
     */
    private final UrlBuilder theBuilder;

    @Autowired
    public DefaultUrlMapper( final UrlBuilder urlBuilder )
    {
        theBuilder = urlBuilder;
    }

    @Override
    public void addMapping( final String alias, final URL original )
    {
        theShortToLongMap.put( alias, original );
        theLongToShortMap.put( original, alias );
    }

    @Override
    public URL toAlias( final URL longUrl,
                        final String protocol,
                        final String host,
                        final int port,
                        final String contextPath ) throws MappingNotFoundDeviation
    {

        final URL shortenedURL;
        if( theLongToShortMap.containsKey( longUrl ) )
        {
            shortenedURL = theBuilder.newUrl( protocol, host, port, contextPath, theLongToShortMap.get( longUrl ) );
        }
        else
        {
            throw new MappingNotFoundDeviation( "URL " + longUrl + " is not currently aliased!" );
        }
        return shortenedURL;
    }

    @Override
    public URL toOriginal( final String alias ) throws MappingNotFoundDeviation
    {
        final URL original;
        if( theShortToLongMap.containsKey( alias ) )
        {
            original = theShortToLongMap.get( alias );
        }
        else
        {
            throw new MappingNotFoundDeviation( "The alias " + alias + " is not currently mapped." );
        }
        return original;
    }

    @Override
    public boolean containsOriginal( final URL original )
    {
        return theLongToShortMap.containsKey( original );
    }
}
